{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "3d16226b-66ce-4e45-8585-fd75a486a019",
   "metadata": {},
   "outputs": [],
   "source": [
    "class ReferenceFrame:\n",
    "    # def __init__(self, velocity=0):\n",
    "    #     self.v = velocity  # 速度，以光速 c 为单位\n",
    "    #     self.gamma = 1 / sqrt(1 - velocity**2) if velocity != 1 else infinity  \n",
    "    def __init__(self, velocity=0):\n",
    "        self.v = velocity  # 速度，以光速 c 为单位（无量纲）\n",
    "        self._validate_velocity()\n",
    "        self.gamma = 1 / sqrt(1 - self.v**2) if abs(self.v) < 1 else infinity # 洛伦兹因子\n",
    "        self.rapidity = self._calculate_rapidity()\n",
    "\n",
    "    def relative_velocity(self, other):\n",
    "        \"\"\"计算另一参考系相对于当前参考系的相对速度\"\"\"\n",
    "        return (other.v - self.v) / (1 - self.v * other.v)\n",
    "        # 其中一个速度是0的话，另一个自然就是原来的v或-v了\n",
    "        # 相互之间的相对速度，交换之后只有符号差别而没有数值差别\n",
    "        # 不过确实不是简单的减法了，而是有个分母\n",
    "        # 这个分母具体是什么东西……我自己还不太清楚\n",
    "\n",
    "    def lorentz_transform(self, t, x, other):\n",
    "        \"\"\"将事件 (t, x) 从当前参考系变换到另一参考系，返回 (t', x')\"\"\"\n",
    "        u = self.relative_velocity(other)\n",
    "        gamma = 1 / sqrt(1 - u**2) if u != 1 else infinity\n",
    "        t_prime = gamma * (t - u * x)\n",
    "        x_prime = gamma * (x - u * t)\n",
    "        return (t_prime, x_prime)\n",
    "\n",
    "    def time_dilation(self, proper_time, other):\n",
    "        \"\"\"计算原时 (当前系) 在另一参考系中的时间膨胀\"\"\"\n",
    "        u = abs(self.relative_velocity(other))  # 速度取绝对值\n",
    "        gamma = 1 / sqrt(1 - u**2) if u != 1 else infinity\n",
    "        return gamma * proper_time\n",
    "\n",
    "    def length_contraction(self, proper_length, other):\n",
    "        \"\"\"计算原长 (当前系) 在另一参考系中的长度收缩\"\"\"\n",
    "        u = abs(self.relative_velocity(other))  # 速度取绝对值\n",
    "        gamma = 1 / sqrt(1 - u**2) if u != 1 else infinity\n",
    "        return proper_length / gamma\n",
    "\n",
    "    def velocity_addition(self, w, other):\n",
    "        \"\"\"将当前参考系中的速度 w 转换为另一参考系中的速度\"\"\"\n",
    "        u = self.relative_velocity(other)\n",
    "        return (w - u) / (1 - w * u)\n",
    "        # 纵向速度叠加，书上19页\n",
    "        # 另外在20页还有横向的……横向这边的推导有点离谱（太复杂了）\n",
    "\n",
    "    ################\n",
    "    #出了点问题……\n",
    "    \n",
    "\n",
    "    #super(ReferenceFrame)\n",
    "    \n",
    "\n",
    "    def _validate_velocity(self):\n",
    "        \"\"\"检查速度是否合法（|v| < 1）\"\"\"\n",
    "        if abs(self.v) >= 1:\n",
    "            raise ValueError(\"速度绝对值必须小于光速 (|v| < 1)\")\n",
    "\n",
    "    def _calculate_rapidity(self):\n",
    "        \"\"\"计算快度 w = arctanh(v)\"\"\"\n",
    "        if abs(self.v) == 1:\n",
    "            return infinity if self.v > 0 else -infinity\n",
    "        return arctanh(self.v)\n",
    "\n",
    "    def relativistic_mass(self, rest_mass):\n",
    "        \"\"\"计算相对论质量 m = γm₀\"\"\"\n",
    "        return self.gamma * rest_mass\n",
    "\n",
    "    def momentum(self, rest_mass):\n",
    "        \"\"\"计算动量 p = γm₀v\"\"\"\n",
    "        return self.gamma * rest_mass * self.v\n",
    "\n",
    "    def add_rapidity(self, delta_w):\n",
    "        \"\"\"通过快度叠加生成新参考系（w_total = w + delta_w）\"\"\"\n",
    "        new_w = self.rapidity + delta_w\n",
    "        new_v = tanh(new_w)\n",
    "        return ReferenceFrame(new_v)\n",
    "\n",
    "    def transform_momentum(self, energy, momentum, other):\n",
    "        \"\"\"将能量和动量从当前参考系变换到另一参考系（一维情况）\"\"\"\n",
    "        u = self.relative_velocity(other)\n",
    "        gamma_u = 1 / sqrt(1 - u**2)\n",
    "        # 洛伦兹变换矩阵（简化为速度沿x轴）\n",
    "        energy_prime = gamma_u * (energy - u * momentum)\n",
    "        momentum_prime = gamma_u * (momentum - u * energy)\n",
    "        return (energy_prime, momentum_prime)\n",
    "\n",
    "    # 保留原有方法（如 relative_velocity, lorentz_transform 等）"
   ]
  },
  {
   "cell_type": "raw",
   "id": "704ad9e6-bbef-4d65-a5ed-87e173d59f3c",
   "metadata": {},
   "source": [
    "不过话说回来，这堆洛伦兹变变换的公式咱还没有好好研究过……\n",
    "目前用的时钟、长度、速度变换都是一种现有的公式，但是没有从洛伦兹变换推导过来\n",
    "也算是一个待办吧……"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "951da23a-9c37-45f5-a3de-11ed63daaf40",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "例题1：地球观测到飞船时间膨胀为 1.66666666666667 小时\n",
      "例题2：运动杆的观测长度 8.00000000000000 米\n",
      "例题3：飞船B相对于A的速度为 -0.975609756097561c\n"
     ]
    }
   ],
   "source": [
    "# 示例 1：时间膨胀 (飞船以 0.8c 飞行)\n",
    "earth = ReferenceFrame(0)\n",
    "spaceship = ReferenceFrame(0.8)\n",
    "proper_time = 1  # 飞船上的1小时\n",
    "dilated_time = spaceship.time_dilation(proper_time, earth)\n",
    "print(f\"例题1：地球观测到飞船时间膨胀为 {dilated_time.n()} 小时\")\n",
    "\n",
    "# 示例 2：长度收缩 (10米长杆以 0.6c 运动)\n",
    "rod_length = 10\n",
    "contracted_length = earth.length_contraction(rod_length, ReferenceFrame(0.6))\n",
    "print(f\"例题2：运动杆的观测长度 {contracted_length.n()} 米\")\n",
    "\n",
    "# 示例 3：速度叠加 (A: 0.6c 向东，B: 0.8c 向西)\n",
    "spaceship_B = ReferenceFrame(-0.8)\n",
    "u_relative = spaceship.relative_velocity(spaceship_B)\n",
    "print(f\"例题3：飞船B相对于A的速度为 {u_relative.n()}c\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d9d7a387-5e27-455c-9240-95c71cc99b74",
   "metadata": {},
   "source": [
    "习题1：一飞船以 0.99c 速度经过地球，飞船内经历 1 年。地球观测者记录的时间是多少？"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "a96e9c80-866b-426d-a04c-a608a28eeb67",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "习题1：地球记录时间：7.08881205008335 年\n"
     ]
    }
   ],
   "source": [
    "ship = ReferenceFrame(0.99)\n",
    "earth_time = ship.time_dilation(1, earth)\n",
    "print(f\"习题1：地球记录时间：{earth_time.n()} 年\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9873b77b-9cbc-42dc-9c20-1c139c5f9055",
   "metadata": {},
   "source": [
    "习题2：静止长度 2m 的火箭以 0.8c 运动，计算其观测长度。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "f93ad175-0012-4993-9aef-af899bb682bd",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "习题2：观测长度：1.20000000000000 米\n"
     ]
    }
   ],
   "source": [
    "contracted = earth.length_contraction(2, ReferenceFrame(0.8))\n",
    "print(f\"习题2：观测长度：{contracted.n()} 米\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e553ccdd-74a4-4233-99d9-45e974cd32e9",
   "metadata": {},
   "source": [
    "习题3：两个飞船分别以 0.7c 和 0.9c 同方向飞行，计算它们的相对速度。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "d66431f9-efbd-4bc6-a981-486f60cefccd",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "习题3：相对速度：0.540540540540541c\n"
     ]
    }
   ],
   "source": [
    "ship1 = ReferenceFrame(0.7)\n",
    "ship2 = ReferenceFrame(0.9)\n",
    "print(f\"习题3：相对速度：{ship1.relative_velocity(ship2).n()}c\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1f145cd9-2156-48f6-976a-ed2ce530a309",
   "metadata": {},
   "source": [
    "关键公式说明\n",
    "\n",
    "    时间膨胀：Δt = γΔt₀\n",
    "\n",
    "        γ = 1/√(1-v²/c²)\n",
    "\n",
    "    长度收缩：L = L₀/γ\n",
    "\n",
    "    速度叠加：w' = (w - u)/(1 - wu/c²)\n",
    "\n",
    "    相对速度：u = (v₂ - v₁)/(1 - v₁v₂/c²)\n",
    "\n",
    "此实现假设所有运动沿 x 轴方向，速度以光速 c 为单位（即数值 0.8 表示 0.8c）。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "abe394ab-da89-491c-ae28-62ae10951c7f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "示例1：速度 0.800000000000000c 对应的快度 w = 1.09861228866811\n",
      "示例2：速度 0.800000000000000c 下的相对论质量 = 1.66666666666667 kg\n",
      "动量 p = 1.33333333333333 kg·c\n",
      "示例3：原速度 0.800000000000000c → 新速度 0.921459398899899c\n"
     ]
    }
   ],
   "source": [
    "# 示例 1：快度与速度的转换\n",
    "v = 0.8\n",
    "frame = ReferenceFrame(v)\n",
    "print(f\"示例1：速度 {v}c 对应的快度 w = {frame.rapidity.n()}\")\n",
    "\n",
    "# 示例 2：相对论质量与动量\n",
    "rest_mass = 1  # 静质量 m₀ = 1 kg\n",
    "print(f\"示例2：速度 {v}c 下的相对论质量 = {frame.relativistic_mass(rest_mass).n()} kg\")\n",
    "print(f\"动量 p = {frame.momentum(rest_mass).n()} kg·c\")\n",
    "\n",
    "# 示例 3：快度叠加（叠加快度 w=0.5）\n",
    "new_frame = frame.add_rapidity(0.5)\n",
    "print(f\"示例3：原速度 {v}c → 新速度 {new_frame.v.n()}c\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "452ec006-7ec0-469e-9361-22bf88107d7f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "习题1：快度 = 2.64665241236225\n",
      "动量 (m₀=1) = 7.01792392958252 kg·c\n"
     ]
    }
   ],
   "source": [
    "# 习题1：计算速度为 0.99c 时的快度和动量\n",
    "high_speed_frame = ReferenceFrame(0.99)\n",
    "print(f\"习题1：快度 = {high_speed_frame.rapidity.n()}\")\n",
    "print(f\"动量 (m₀=1) = {high_speed_frame.momentum(1).n()} kg·c\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "e4a78a61-1a3a-4ec4-99fb-eed1cfcb55a0",
   "metadata": {},
   "outputs": [
    {
     "ename": "AttributeError",
     "evalue": "'ReferenceFrame' object has no attribute 'relative_velocity'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[36], line 4\u001b[0m\n\u001b[1;32m      2\u001b[0m energy, momentum \u001b[38;5;241m=\u001b[39m RealNumber(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m3.0\u001b[39m\u001b[38;5;124m'\u001b[39m), RealNumber(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m0.8\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m      3\u001b[0m new_frame \u001b[38;5;241m=\u001b[39m ReferenceFrame(RealNumber(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m0.6\u001b[39m\u001b[38;5;124m'\u001b[39m))\n\u001b[0;32m----> 4\u001b[0m energy_prime, momentum_prime \u001b[38;5;241m=\u001b[39m \u001b[43mnew_frame\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtransform_momentum\u001b[49m\u001b[43m(\u001b[49m\u001b[43menergy\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmomentum\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mReferenceFrame\u001b[49m\u001b[43m(\u001b[49m\u001b[43mInteger\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m      5\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m习题2：变换后能量 = \u001b[39m\u001b[38;5;132;01m{\u001b[39;00menergy_prime\u001b[38;5;241m.\u001b[39mn()\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m, 动量 = \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mmomentum_prime\u001b[38;5;241m.\u001b[39mn()\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n",
      "Cell \u001b[0;32mIn[33], line 36\u001b[0m, in \u001b[0;36mReferenceFrame.transform_momentum\u001b[0;34m(self, energy, momentum, other)\u001b[0m\n\u001b[1;32m     34\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mtransform_momentum\u001b[39m(\u001b[38;5;28mself\u001b[39m, energy, momentum, other):\n\u001b[1;32m     35\u001b[0m \u001b[38;5;250m    \u001b[39m\u001b[38;5;124;03m\"\"\"将能量和动量从当前参考系变换到另一参考系（一维情况）\"\"\"\u001b[39;00m\n\u001b[0;32m---> 36\u001b[0m     u \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrelative_velocity\u001b[49m(other)\n\u001b[1;32m     37\u001b[0m     gamma_u \u001b[38;5;241m=\u001b[39m Integer(\u001b[38;5;241m1\u001b[39m) \u001b[38;5;241m/\u001b[39m sqrt(Integer(\u001b[38;5;241m1\u001b[39m) \u001b[38;5;241m-\u001b[39m u\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mInteger(\u001b[38;5;241m2\u001b[39m))\n\u001b[1;32m     38\u001b[0m     \u001b[38;5;66;03m# 洛伦兹变换矩阵（简化为速度沿x轴）\u001b[39;00m\n",
      "\u001b[0;31mAttributeError\u001b[0m: 'ReferenceFrame' object has no attribute 'relative_velocity'"
     ]
    }
   ],
   "source": [
    "# 习题2：能量-动量变换（当前系中能量=3, 动量=0.8）\n",
    "energy, momentum = 3.0, 0.8\n",
    "new_frame = ReferenceFrame(0.6)\n",
    "energy_prime, momentum_prime = new_frame.transform_momentum(energy, momentum, ReferenceFrame(0))\n",
    "print(f\"习题2：变换后能量 = {energy_prime.n()}, 动量 = {momentum_prime.n()}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5acea6ac-b676-4c04-972b-5b54135eb866",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "SageMath 10.5",
   "language": "sage",
   "name": "sagemath"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
